#pragma once

#include "FLOW_core/container_types.h"
#include "FLOW_core/core_types.h"
#include "FLOW_core/namespace.h"
#include "FLOW_ents/namespace.h"

namespace CORE
{
	class CStrId;
}

using namespace CORE;

#define ENTITYMGR ENTS::CEntityMgr::GetInstance( )

namespace ENTS
{
	class CEntity;

	/*!
	 * \brief Manager that controls the update and lifecycle of the logical entities
	 * 
	 * Manager that controls the update and lifecycle of the logical entities
	 */
	class CEntityMgr
	{
	private:

		//======================== DATA TYPE DEFINITIONS ======================
		typedef CHashMap< u32_t, CEntity* > THMEnts;

		//============================ DATA MEMBERS ===========================

		//! Unique instance of the manager
		static CEntityMgr* sg_ents_mgr;

		//! hash table that contains all the entities associated to its name
		THMEnts				m_hm_ents;

	public:

		//============================== METHODS ==============================

		//! Return the unique instance of the manager
		static CEntityMgr* GetInstance( void );

		//! Initialized the manager
		bool_t Initialize( void );

		//! Shutdowns the manager
		bool_t Shutdown( void );

		//! Updates the manager
		void Update( void );

		//! Register an entity if not registered yet
		bool_t RegisterEntity( CEntity* ap_ent );

		//! Unregisters a preoviously registered entity
		bool_t UnregisterEntity( CEntity* ap_ent );

		//! Gets the reference to an entity by its name, NULL if the specified name does not appears in the manager
		CEntity* GetEntityByName( CStrId& ar_ent_name );

	private:

		//============================== METHODS ==============================

		//! Default constructor
		CEntityMgr( );

		//! Destructor
		~CEntityMgr( );

		//! Copy constructor
		CEntityMgr( const CEntityMgr& ar_ent_mgr );

		//! Assignment operator
		CEntityMgr& operator = ( const CEntityMgr& ar_ent_mgr );
	};

} //namespace ENTS